#!/usr/bin/env python3
import urllib.request
import urllib.parse
from urllib.error import HTTPError

def query_doi(doi):
    url = 'http://dx.doi.org/' + doi
    return query_url(url)
    # req = urllib.request.Request(url)
    # req.add_header('Accept', 'application/x-bibtex')
    # with urllib.request.urlopen(req) as f:
    #     bibtex = f.read().decode()
    # return bibtex

def query_url(url):
    req = urllib.request.Request(url)
    req.add_header('Accept', 'application/x-bibtex')
    with urllib.request.urlopen(req) as f:
        bibtex = f.read().decode()
    return bibtex
import re
WORD_RE=re.compile(r'[a-zA-Z0-9]+')
def fetch_url(url):
    req = urllib.request.Request(url)
    txt = urllib.request.urlopen(req).read().decode()
    titlest = txt.find("<title>")
    titleed = txt.find('</title>')
    title = txt[titlest+len('<title>'):titleed].strip()
    return "online", WORD_RE.search(title), {'url': '{' + urllib.parse.unquote(url) + '}', 'title': '{' + title + '}'}
def parse_bib(s):
    #for i in range(len(s)):
    bibtype = s[s.find('@'):s.find('{')][1:]
    bibkey = s[s.find('{'):s.find(',')][1:]
    # print(bibtype)
    # print(bibkey)
    bibcont = s[s.find(','):s.rfind('}')][1:]
    # print(bibcont)
    st = 0
    kv = {}
    while True:
        ed = bibcont.find(',', st)
        if ed == -1:
            break
        while (ed != -1 and bibcont[st:ed].count('{') != bibcont[st:ed].count('}')):
            ed = bibcont.find(',', ed+1)
        if ed == -1:
            ed = len(bibcont)
        # print(bibcont[st:ed])
        # print(st, ed)
        opt = bibcont[st:ed]
        k,v = map(str.strip, opt.split('=', 1))
        kv[k] = v
        st = ed + 1
    return bibtype, bibkey, kv

def remake_key(kv):
    author0 = "missing"
    if 'author' in kv:
        authors = kv['author']
        while (authors.startswith('{') and authors.endswith('}')):
            authors = authors[1:-1].strip()
        author = authors.split(' and ')[0]
        if author.find(',') != -1:
            author0 = author.split(',')[0].strip()
        else:
            author0 = author.split(' ')[-1]
    year = "0000"
    if 'year' in kv:
        year = kv['year']
        while (year.startswith('{') and year.endswith('}')):
            year = year[1:-1].strip()
    title0 = "missing"
    if 'title' in kv:
        title = kv['title']
        title0 = WORD_RE.search(title).group()
    return (author0+year+title0).lower()
def assemble_bib(bibtype, bibkey, kv):
    parts = ["@%s{%s," % (bibtype, bibkey)]
    spl = 0
    for k, v in kv.items():
        if len(k) > spl:
            spl = len(k)
    for k, v in kv.items():
        parts.append('    %s%s = %s,' % (k, " "*(spl-len(k)), v))
    parts.append('}')
    return '\n'.join(parts) + '\n'

import sys
import argparse
import json
#" and ".join(map(lambda p: " ".join(list(map(lambda s: s[0] + '.', p[:-1])) + [p[-1]]), map(lambda x: SP_RE.split(x), AND_RE.split(alist))))
parser = argparse.ArgumentParser()
parser.add_argument('-ol', action='store_true', default=False)
parser.add_argument('-a', type=str, default=None)
parser.add_argument('-y', type=str, default=None)
parser.add_argument('-f', action='store_true', default=False)
parser.add_argument('-ok', action='store_true', default=False)
parser.add_argument('doi')
args = parser.parse_args(sys.argv[1:])
vdict = {}
# if args.a:
#     vdict['author'] = args.a
#print(args)
if args.ol:
    t, k, a = fetch_url(args.doi)
else:
    if args.f:
        text = query_url(args.doi)
    else:
        text = query_doi(args.doi)
    # print(text)
    t, k, a = parse_bib(text)
if args.a:
    a['author'] = "{%s}" % args.a
if args.y:
    a['year'] = args.y
if 'author' not in a:
    a['author'] = "{%s}" % "anon."
if not args.ok:
    k = remake_key(a)
# set_var(entry, vdict)
# reset_key(entry)
print(assemble_bib(t, k, a))
print('found bib item %s' % k, file=sys.stderr)
